﻿using System;
using System.Windows;
using nRoute.Behaviors.Interactivity;
using System.ComponentModel;
using System.Windows.Data;
using nRoute.Components.TypeConverters;

namespace nRoute.Behaviors.Triggers
{
    /// <summary>
    /// Represents a trigger that can match a value being equal to the given value.
    /// </summary>
    public class ValueMatchTrigger
		 : BindableTriggerBase<FrameworkElement>
    {
        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register("Source", typeof(object), typeof(ValueMatchTrigger), 
            new PropertyMetadata(null, new PropertyChangedCallback(OnSourceChanged)));

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(object), typeof(ValueMatchTrigger),
            new PropertyMetadata(null));

        private bool _negate;

#region Properties

        [Category("Common Properties")]
        public object Source
        {
            get { return GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }

        [Category("Common Properties")]
#if SILVERLIGHT
        [TypeConverter(typeof(nRoute.Components.TypeConverters.ConvertFromStringConverter))]
#endif
        public Object Value
        {
            get { return GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        [Category("Common Properties")]
        public bool Negate
        {
            get { return _negate; }
            set { _negate = value; }
        }

#if SILVERLIGHT

        [Category("Common Properties")]
        public Binding SourceBinding
        {
            get { return GetBinding(SourceProperty); }
            set { SetBinding<object>(SourceProperty, value); }
        }

        [Category("Common Properties")]
        public Binding ValueBinding
        {
            get { return GetBinding(ValueProperty); }
            set { SetBinding<object>(ValueProperty, value); }
        }

#endif

#endregion

#region Handlers

        private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ValueMatchTrigger)d).CompareValue(e.NewValue);
        }

        private void CompareValue(object sourceValue)
        {
            if (this.AssociatedObject == null) return;      // this is to ensure with initial/static set properties the trigger isn't invoked

            // we need to convert it so that the maching can be done
            var _matchValue = sourceValue != null ? ConverterHelper.ConvertToType(Value, sourceValue.GetType()) : null;
            var _result = object.Equals(_matchValue, sourceValue);
            if (Negate) _result = !_result;
            if (_result) base.InvokeActions(sourceValue);
        }

#endregion

    }
}
